package com.jiajia.aspectj;

import com.jiajia.annotation.DataSource;
import com.jiajia.datasource.DynamicDatasourceContextHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;


/**
 * @author zjiajia
 * @date 2024/7/9 15:03
 */
@Aspect
@Component
public class DataSourceAspect {

    @Pointcut("@annotation(com.jiajia.annotation.DataSource) || @within(com.jiajia.annotation.DataSource)")
    public void pc(){

    }

    @Around("pc()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
        DataSource dataSource = getDataSource(proceedingJoinPoint);
        if(dataSource != null){
            DynamicDatasourceContextHolder.setDataSourceType(dataSource.value());
        }
        try{
            return proceedingJoinPoint.proceed();
        }catch (Throwable throwable) {
            throwable.printStackTrace();
            throw throwable;
        }finally {
            DynamicDatasourceContextHolder.clearDataSourceType();
        }

    }

    public DataSource getDataSource(ProceedingJoinPoint pj){
        MethodSignature methodSignature = (MethodSignature) pj.getSignature();
        DataSource dataSource = AnnotationUtils.findAnnotation(methodSignature.getMethod(), DataSource.class);
        // 返回方法上的 @DataSource 注解
        if(dataSource != null){
            return dataSource;
        }
        // 返回类上的 @DataSource 注解
        return AnnotationUtils.findAnnotation(methodSignature.getDeclaringType(),DataSource.class);
    }
}
